package com.itheima.search.service.impl;

import com.heima.es.service.EsService;
import com.heima.model.common.VO.SearchArticleVO;
import com.heima.model.common.constants.es.EsConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.dtos.UserSearchDTO;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.threadlocal.AppThreadLocalUtils;
import com.heima.model.common.user.pojo.ApUser;
import com.itheima.common.exception.CustException;
import com.itheima.search.service.ApUserSearchService;
import com.itheima.search.service.ArticleSearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.queryparser.xml.builders.BooleanQueryBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {
    @Value("${file.minio.readPath}")
    String readPath;
    @Autowired
    EsService<SearchArticleVO> esService;
    @Value("${file.oss.web-site}")
    private String webSite;
    @Autowired
    private ApUserSearchService apUserSearchService;
    @Override
    public ResponseResult search(UserSearchDTO userSearchDto) {
        //1 参数检查
        if (userSearchDto==null || userSearchDto.getSearchWords()==null){
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        String searchWords = userSearchDto.getSearchWords();
        //2 构建查询条件执行查询
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 构建查询条件和过滤等
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        // 关键词查询
        MatchQueryBuilder title = QueryBuilders.matchQuery("title", searchWords);//查找标签
        boolQueryBuilder.must(title);
        // 查询小于mindate的数据
        if (userSearchDto.getMinBehotTime()==null){
            userSearchDto.setMinBehotTime(new Date());
        }
        RangeQueryBuilder publishTime = QueryBuilders.rangeQuery("publishTime").lt(userSearchDto.getMinBehotTime());
        boolQueryBuilder.filter(publishTime);
        // 分页
        searchSourceBuilder.from(0);//不需要设置从哪开始
        searchSourceBuilder.size(userSearchDto.getPageSize());
        // 按照发布时间倒序
        searchSourceBuilder.sort("publishTime", SortOrder.DESC);
        // 高亮 三要素
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");//标签字段
        highlightBuilder.preTags("<font style='color: red; font-size: inherit;'>");
        highlightBuilder.postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);
        searchSourceBuilder.query(boolQueryBuilder);
        PageResponseResult search = esService.search(searchSourceBuilder, SearchArticleVO.class, EsConstants.ARTICLE_INDEX_NAME);
        //4 返回结果 staticUrl 需要拼接 minIO文章服务器的前缀路径
        if (search==null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        List<SearchArticleVO> searchArticleVOS= (List<SearchArticleVO>)search.getData();
        for (SearchArticleVO searchArticleVO : searchArticleVOS) {
            searchArticleVO.setStaticUrl(readPath+searchArticleVO.getStaticUrl());
            searchArticleVO.setImages(webSite+searchArticleVO.getImages());
        }
        //记录搜索记录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user!=null){
            userSearchDto.setEntryId(user.getId());
        }
        //异步调用存储记录
        apUserSearchService.insert( userSearchDto);
        return search;

    }

    @Override
    public void saveArticle(SearchArticleVO article) {
        esService.save(article,EsConstants.ARTICLE_INDEX_NAME);
    }

    @Override
    public void deleteArticle(String articleId) {
        esService.createIndex(EsConstants.ARTICLE_INDEX_NAME,articleId);

    }
}
